home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-25 | 4.9 KB | 204 lines | [TEXT/MPS ] |
- /*
- File: DialogWindow.cp
-
- Contains: Implementation of a base class for Modeless Dialogs
-
- Written by: Dave Falkenburg
-
- Copyright: © 1993-94 by Dave Falkenburg, all rights reserved.
-
- Change History (most recent first):
-
- To Do:
- */
-
- #include <Dialogs.h>
- #include <Menus.h>
- #include <Desk.h>
- #include <Traps.h>
- #include <Devices.h>
-
- #include "DialogWindow.h"
- #include "AppLib.h"
-
-
- TDialogWindow::TDialogWindow(DialogTemplateID dialogTemplateID)
- {
- fTemplateID = dialogTemplateID;
- this->CreateWindow(kNormalWindow);
- }
-
-
- WindowPtr
- TDialogWindow::MakeNewWindow(WindowPtr behindWindow)
- {
- return GetNewDialog(fTemplateID,nil,behindWindow);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////
- //
- // EventFilter strategy for Dialog Window
- //
- // Because of the need to patch and unpatch FrontWindow when calling IsDialogEvent
- // and DialogSelect, only do these things when a Modless Dialog is the frontmost
- // window. (e.g., it’s event filter is active)
- //
- // NOTE: We always pass events through, except when an item has been hit.
- //
- // You may be thinking that it is easier to just rewrite the Dialog Manager in
- // this program. You’re probably right.
-
- pascal WindowPtr FrontWindowPatchForDialogs();
-
-
- pascal WindowPtr
- FrontWindowPatchForDialogs()
- {
- return FrontNonFloatingWindow();
- }
-
- #define uppFrontWindowPatchProcInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
-
- UniversalProcPtr FrontWindowPatchUPP
- = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) &FrontWindowPatchForDialogs,uppFrontWindowPatchProcInfo,GetCurrentISA());
-
-
- Boolean
- TDialogWindow::EventFilter(EventRecord *theEvent)
- {
- UniversalProcPtr oldFrontWindow = GetToolboxTrapAddress(_FrontWindow);
- DialogPtr aDialog;
- Boolean eventHasBeenGobbled = false;
- short aDialogItem;
- short oldWindowKind;
-
- // Don’t snarf keypresses meant for menus
- if ((theEvent->what == keyDown) && (theEvent->modifiers & cmdKey))
- return false;
-
- // Patch in our version of FrontWindow so that IsDialogEvent will do the right
- // thing. DialogManager should check both frontmost floating and frontmost
- // non-floating windows, however we don’t support floating dialogs.
- SetToolboxTrapAddress(FrontWindowPatchUPP,_FrontWindow);
-
- // Jam the windowKind of our dialog window back to dialogKind so that the
- // Dialog Manager can recognize our window as a dialog window.
- oldWindowKind = ((WindowPeek) fWindow)->windowKind;
- ((WindowPeek) fWindow)->windowKind = dialogKind;
-
- if (IsDialogEvent(theEvent))
- if (DialogSelect(theEvent,&aDialog,&aDialogItem))
- eventHasBeenGobbled = true;
-
- // Restore the windowKind
- ((WindowPeek) fWindow)->windowKind = oldWindowKind;
-
- // Put FrontWindow back the way it really belongs
- SetToolboxTrapAddress((UniversalProcPtr) oldFrontWindow,_FrontWindow);
-
- if (eventHasBeenGobbled)
- {
- ItemHit(aDialogItem); // Call user’s method to deal with a hit
- return true;
- }
-
- return(false);
- }
-
-
- void
- TDialogWindow::Activate(Boolean activating)
- {
- /* (De)activates are NOT automagically handled because our floating
- * windows prevent real activate events from ever being generated
- * for any non-floaters windows.
- *
- * Our strategy is to fool the dialog manager into thinking that
- * things are still fine by passing it a fake (de)activate event.
- *
- * Luckily, we don’t have to patch FrontWindow to make DialogSelect
- * work for activate and update events.
- */
-
- EventRecord fakeEvent;
-
- OSEventAvail(0,&fakeEvent); // Get an intialized, but otherwise empty event record
-
- fakeEvent.what = activateEvt;
- fakeEvent.message = (unsigned long) fWindow;
- if (activating)
- fakeEvent.modifiers |= activeFlag;
- else
- fakeEvent.modifiers &= ~activeFlag;
-
- // Pass event on to DialogSelect
-
- DialogPtr aDialog;
- short aDialogItem;
-
- (void) DialogSelect(&fakeEvent,&aDialog,&aDialogItem);
- }
-
-
- void
- TDialogWindow::Draw(void)
- {
- // Automagically handled by Dialog Manager when we are
- // the frontmost window, but not at other times because
- // we only set the windowKind to dialogKind inside our
- // EventFilter (which is only active when we are frontmost).
-
- UpdateDialog((DialogPtr) fWindow, fWindow->visRgn);
- }
-
-
- void
- TDialogWindow::Click(EventRecord * /* anEvent */)
- {
- /* The only time this method is called is to handle a click
- * when the dialog window isn’t frontmost. All other times,
- * DialogSelect will do everything for us.
- *
- * If our dialog contains useritems with the ability to
- * be the source of a drag we’d need to start drag tracking
- * in here.
- */
-
- this->Select();
- }
-
-
- void
- TDialogWindow::DoEditMenu(short item)
- {
- switch (item+accMenu)
- {
- case accUndo:
- break;
-
- case accCut:
- DlgCut((DialogPtr) &fWindow);
- break;
-
- case accCopy:
- DlgCopy((DialogPtr) &fWindow);
- break;
-
- case accPaste:
- DlgPaste((DialogPtr) &fWindow);
- break;
-
- case accClear:
- DlgDelete((DialogPtr) &fWindow);
- break;
- }
- }
-
-
- void
- TDialogWindow::ItemHit(short /* theItem */)
- {
- /* Override this function to handle dialog items */
- }
-